﻿#include <stdbool.h>
#include <gtk/gtk.h>
#include <curl/curl.h>
#include <json-c/json.h>
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include <time.h>
#include <ctype.h>
#ifdef _WIN32
#include <windows.h>
#endif

#ifdef __MINGW32__
#include <stdlib.h>
char* strndup(const char* s, size_t n) {
    char* p;
    size_t len = strlen(s);
    len = (n < len) ? n : len;
    p = malloc(len + 1);
    if(p) {
        memcpy(p, s, len);
        p[len] = '\0';
    }
    return p;
}
#endif

typedef struct {
    char* memory;
    size_t size;
} MemoryStruct;

typedef struct {
    char* model;
    bool is_first_chunk;
} StreamContext;

typedef struct {
    char* role;
    char* content;
} ChatMessage;

static GtkWidget* model_combo;
static GtkWidget* input_entry;
static GtkWidget* chat_view;
static GtkTextBuffer* chat_buffer;
static GtkTextTag* user_tag;
static GtkTextTag* assistant_tag;
static GtkTextTag* timestamp_tag;
static int current_font_size = 14;

// AI响应状态相关变量
static GtkWidget *send_button = NULL;
static volatile bool is_ai_responding = false;
static CURL *current_curl = NULL;

// 历史记录相关变量
static GQueue *history = NULL;
static gint history_pos = -1;
static gchar *current_editing = NULL;

// 添加聊天记录文件路径
static char chat_history_file[1024];
static char chat_input_history_file[1024];

// 添加互斥锁保护
static bool cleanup_in_progress = false;

// 添加配置文件路径
static char default_model_file[1024];

// 保存聊天记录到文件
static void save_chat_message(const char* role, const char* content) {
    if (!role || !content) {
        g_warning("Invalid parameters in save_chat_message");
        return;
    }
    // 添加文件操作的错误处理
    FILE* fp = fopen(chat_history_file, "a");
    if (!fp) {
        g_warning("Failed to open chat history file: %s (errno: %d)", 
                  strerror(errno), errno);
        return;
    }
    time_t now;
    struct tm* timeinfo;
    char timestamp[64];
    
    time(&now);
    timeinfo = localtime(&now);
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", timeinfo);
    
    fprintf(fp, "[%s] %s: %s\n", timestamp, role, content);
    fclose(fp);
}

// 保存输入历史到文件
static void save_input_history(const char* input) {
    FILE* fp = fopen(chat_input_history_file, "a");
    if (fp) {
        fprintf(fp, "%s\n", input);
        fclose(fp);
    }
}

// 加载历史记录
static void load_history() {
    // 加载输入历史
    FILE* fp = fopen(chat_input_history_file, "r");
    if (fp) {
        char line[4096];
        while (fgets(line, sizeof(line), fp)) {
            size_t len = strlen(line);
            if (len > 0 && line[len-1] == '\n') {
                line[len-1] = '\0';
            }
            g_queue_push_tail(history, g_strdup(line));
        }
        fclose(fp);
    }
    
    // 加载聊天记录
    fp = fopen(chat_history_file, "r");
    if (fp) {
        char line[4096];
        GtkTextIter iter;
        gtk_text_buffer_get_end_iter(chat_buffer, &iter);
        
        while (fgets(line, sizeof(line), fp)) {
            if (strstr(line, "] 您: ")) {
                gtk_text_buffer_insert_with_tags(chat_buffer, &iter, line, -1, user_tag, NULL);
            } else if (strstr(line, "] AI: ")) {
                gtk_text_buffer_insert_with_tags(chat_buffer, &iter, line, -1, assistant_tag, NULL);
            } else {
                gtk_text_buffer_insert(chat_buffer, &iter, line, -1);
            }
        }
        fclose(fp);
    }
}

gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) {
    (void)data;
    GtkEntry *entry = GTK_ENTRY(input_entry);
    
    if (event->keyval == GDK_KEY_F11) {
        GtkWindow *window = GTK_WINDOW(widget);
        GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(window));
        GdkWindowState state = gdk_window_get_state(gdk_window);

        if (state & GDK_WINDOW_STATE_FULLSCREEN) {
            gtk_window_unfullscreen(window);
        } else {
            gtk_window_fullscreen(window);
        }
        return TRUE;
    }
    else if (event->keyval == GDK_KEY_q && (event->state & GDK_CONTROL_MASK)) {
        // 清空文本缓冲区
        gtk_text_buffer_set_text(chat_buffer, "", -1);
        
        // 添加一条提示消息
        GtkTextIter iter;
        gtk_text_buffer_get_end_iter(chat_buffer, &iter);
        gtk_text_buffer_insert_with_tags(chat_buffer, &iter, "[已清空聊天记录]\n\n", -1, timestamp_tag, NULL);
        
        // 清空历史记录文件
        FILE* fp = fopen(chat_history_file, "w");
        if (fp) {
            fclose(fp);
        }
        
        return TRUE;
    }
    else if (event->keyval == GDK_KEY_Up || event->keyval == GDK_KEY_Down) {
        const gint history_len = g_queue_get_length(history);
        if(history_len == 0) return FALSE;

        // 保存当前编辑内容
        if(history_pos == -1) {
            const gchar *current = gtk_entry_get_text(entry);
            if(current_editing) g_free(current_editing);
            current_editing = g_strdup(current);
        }

        // 处理方向键
        if(event->keyval == GDK_KEY_Up) {
            if(history_pos == -1) history_pos = history_len - 1;
            else if(history_pos > 0) history_pos--;
        } else {
            if(history_pos < history_len - 1) history_pos++;
            else {
                history_pos = -1;
                gtk_entry_set_text(entry, current_editing ? current_editing : "");
                return TRUE;
            }
        }

        // 更新输入框内容
        if(history_pos >= 0) {
            const gchar *text = g_queue_peek_nth(history, history_pos);
            gtk_entry_set_text(entry, text);
            
            // 将光标移动到文本末尾
            gint pos = strlen(text);
            gtk_editable_set_position(GTK_EDITABLE(entry), pos);
        }
        return TRUE;
    }
    return FALSE;
}

gboolean update_ui(gpointer data) {
    ChatMessage* msg = (ChatMessage*)data;
    GtkTextIter iter;
    GtkAdjustment *adj = gtk_scrolled_window_get_vadjustment(
        GTK_SCROLLED_WINDOW(gtk_widget_get_parent(chat_view)));
    
    // 在插入文本前保存当前滚动位置
    double current_pos = gtk_adjustment_get_value(adj);
    double max_pos = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
    bool was_at_bottom = (max_pos - current_pos < 50.0);
    
    gtk_text_buffer_get_end_iter(chat_buffer, &iter);

    // Get current time
    time_t now;
    struct tm* timeinfo;
    char timestamp[64];
    
    time(&now);
    timeinfo = localtime(&now);
    strftime(timestamp, sizeof(timestamp), "[%Y-%m-%d %H:%M:%S] ", timeinfo);

    if(strcmp(msg->role, "user") == 0) {
        gtk_text_buffer_insert_with_tags(chat_buffer, &iter, timestamp, -1, timestamp_tag, NULL);
        gtk_text_buffer_insert_with_tags(chat_buffer, &iter, "您: ", -1, user_tag, NULL);
        gtk_text_buffer_insert(chat_buffer, &iter, msg->content, -1);
        gtk_text_buffer_insert(chat_buffer, &iter, "\n\n", -1);
        save_chat_message("您", msg->content);
        
        // 用户消息总是滚动到底部
        GtkTextMark* end_mark = gtk_text_buffer_create_mark(chat_buffer, NULL, &iter, FALSE);
        gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(chat_view), end_mark, 0.0, TRUE, 0.0, 1.0);
        gtk_text_buffer_delete_mark(chat_buffer, end_mark);
    }
    else if(strcmp(msg->role, "assistant") == 0) {
        gtk_text_buffer_insert_with_tags(chat_buffer, &iter, timestamp, -1, timestamp_tag, NULL);
        gtk_text_buffer_insert_with_tags(chat_buffer, &iter, "AI: ", -1, assistant_tag, NULL);
        gtk_text_buffer_insert(chat_buffer, &iter, msg->content, -1);
        save_chat_message("AI", msg->content);
        
        // 更新滚动条位置
        while (gtk_events_pending()) gtk_main_iteration();
        max_pos = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
        
        // 如果之前在底部，则保持在底部
        if (was_at_bottom) {
            gtk_adjustment_set_value(adj, max_pos);
        }
    }
    else if(strcmp(msg->role, "") == 0) {
        gtk_text_buffer_insert(chat_buffer, &iter, msg->content, -1);
        
        // 更新滚动条位置
        while (gtk_events_pending()) gtk_main_iteration();
        max_pos = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
        
        // 如果之前在底部，则保持在底部
        if (was_at_bottom) {
            gtk_adjustment_set_value(adj, max_pos);
        }
    }
    else if(strcmp(msg->role, "end") == 0) {
        gtk_text_buffer_insert(chat_buffer, &iter, "\n\n", -1);
        
        // AI响应结束时，如果之前在底部，则滚动到底部
        if (was_at_bottom) {
            GtkTextMark* end_mark = gtk_text_buffer_create_mark(chat_buffer, NULL, &iter, FALSE);
            gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(chat_view), end_mark, 0.0, TRUE, 0.0, 1.0);
            gtk_text_buffer_delete_mark(chat_buffer, end_mark);
        }
    }

    free(msg->role);
    if(msg->content) free(msg->content);
    free(msg);
    return FALSE;
}

static size_t write_callback(void* contents, size_t size, size_t nmemb, void* userp) {
    size_t realsize = size * nmemb;
    MemoryStruct* mem = (MemoryStruct*)userp;
    
    if (!mem->memory) {
        mem->memory = malloc(realsize + 1);
        if (!mem->memory) return 0;
        mem->size = 0;
    } else {
        char* new_memory = realloc(mem->memory, mem->size + realsize + 1);
        if (!new_memory) return 0;
        mem->memory = new_memory;
    }
    
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = '\0';
    return realsize;
}

static size_t stream_callback(void* ptr, size_t size, size_t nmemb, void* userdata) {
    StreamContext* ctx = (StreamContext*)userdata;
    size_t total = size * nmemb;
    char* data = strndup((char*)ptr, total);
    
    char* line = strtok(data, "\n");
    while(line) {
        json_object* json = json_tokener_parse(line);
        if(json) {
            json_object *response, *done;
            
            if(json_object_object_get_ex(json, "response", &response)) {
                const char* text = json_object_get_string(response);
                
                ChatMessage* chunk = malloc(sizeof(ChatMessage));
                chunk->role = ctx->is_first_chunk ? strdup("assistant") : strdup("");
                chunk->content = strdup(text);
                ctx->is_first_chunk = false;
                
                g_idle_add(update_ui, chunk);
            }
            
            if(json_object_object_get_ex(json, "done", &done) && json_object_get_boolean(done)) {
                ChatMessage* end = malloc(sizeof(ChatMessage));
                end->role = strdup("end");
                end->content = NULL;
                g_idle_add(update_ui, end);
            }
            json_object_put(json);
        }
        line = strtok(NULL, "\n");
    }
    free(data);
    return total;
}

// 安全地更新按钮标签的辅助函数
static gboolean update_button_label(gpointer data) {
    (void)data;  // 显式忽略未使用的参数
    if (send_button && GTK_IS_BUTTON(send_button)) {
        gtk_button_set_label(GTK_BUTTON(send_button), "发送");
    }
    return G_SOURCE_REMOVE;
}

void* send_request(void* data) {
    ChatMessage* msg = (ChatMessage*)data;
    current_curl = curl_easy_init();
    
    if(!current_curl) {
        free(msg->role);
        free(msg->content);
        free(msg);
        is_ai_responding = false;
        g_idle_add(update_button_label, NULL);
        return NULL;
    }
    
    StreamContext ctx = {
        .model = strdup(msg->role),
        .is_first_chunk = true
    };
    
    if(!ctx.model) {
        curl_easy_cleanup(current_curl);
        current_curl = NULL;
        free(msg->role);
        free(msg->content);
        free(msg);
        is_ai_responding = false;
        g_idle_add(update_button_label, NULL);
        return NULL;
    }
    
    struct json_object* req = json_object_new_object();
    if(!req) {
        free(ctx.model);
        curl_easy_cleanup(current_curl);
        current_curl = NULL;
        free(msg->role);
        free(msg->content);
        free(msg);
        is_ai_responding = false;
        g_idle_add(update_button_label, NULL);
        return NULL;
    }
    
    json_object_object_add(req, "model", json_object_new_string(ctx.model));
    json_object_object_add(req, "prompt", json_object_new_string(msg->content));
    json_object_object_add(req, "stream", json_object_new_boolean(TRUE));
    
    curl_easy_setopt(current_curl, CURLOPT_URL, "http://localhost:11434/api/generate");
    curl_easy_setopt(current_curl, CURLOPT_POSTFIELDS, json_object_to_json_string(req));
    curl_easy_setopt(current_curl, CURLOPT_WRITEFUNCTION, stream_callback);
    curl_easy_setopt(current_curl, CURLOPT_WRITEDATA, &ctx);
    
    curl_easy_perform(current_curl);
    
    free(ctx.model);
    curl_easy_cleanup(current_curl);
    current_curl = NULL;
    json_object_put(req);
    
    free(msg->role);
    free(msg->content);
    free(msg);
    
    is_ai_responding = false;
    g_idle_add(update_button_label, NULL);
    
    return NULL;
}

// 停止当前的AI响应
static void stop_ai_response() {
    if (is_ai_responding && current_curl) {
        curl_easy_cleanup(current_curl);
        current_curl = NULL;
        is_ai_responding = false;
        g_idle_add(update_button_label, NULL);
        
        // 添加一条消息表示响应被终止
        GtkTextIter iter;
        gtk_text_buffer_get_end_iter(chat_buffer, &iter);
        gtk_text_buffer_insert(chat_buffer, &iter, "\n[响应已终止]\n\n", -1);
    }
}

void send_click(GtkWidget* button, gpointer data) {
    (void)button;
    (void)data;
    
    // 如果AI正在响应，则停止响应
    if (is_ai_responding) {
        stop_ai_response();
        return;
    }
    
    const gchar* model = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(model_combo));
    const gchar* input = gtk_entry_get_text(GTK_ENTRY(input_entry));

    if(!model || !input || strlen(input) == 0) return;

    // 保存到历史记录
    if(g_queue_get_length(history) >= 50) {
        g_free(g_queue_pop_head(history));
    }
    g_queue_push_tail(history, g_strdup(input));
    save_input_history(input);
    
    history_pos = -1;
    if(current_editing) {
        g_free(current_editing);
        current_editing = NULL;
    }

    ChatMessage* user_msg = malloc(sizeof(ChatMessage));
    user_msg->role = strdup("user");
    user_msg->content = strdup(input);
    g_idle_add(update_ui, user_msg);

    ChatMessage* req = malloc(sizeof(ChatMessage));
    req->role = strdup(model);
    req->content = strdup(input);
    
    // 设置AI响应状态
    is_ai_responding = true;
    gtk_button_set_label(GTK_BUTTON(send_button), "停止");
    
    g_thread_new("request", send_request, req);
    gtk_entry_set_text(GTK_ENTRY(input_entry), "");
}

// 保存默认模型设置
static void save_default_model(const char* model_name) {
    if (!model_name) return;
    FILE* fp = fopen(default_model_file, "w");
    if (fp) {
        fprintf(fp, "%s\n", model_name);
        fclose(fp);
    }
}

// 加载默认模型设置
static char* load_default_model() {
    char* default_model = NULL;
    FILE* fp = fopen(default_model_file, "r");
    if (fp) {
        char line[256];
        if (fgets(line, sizeof(line), fp)) {
            size_t len = strlen(line);
            if (len > 0 && line[len-1] == '\n') {
                line[len-1] = '\0';
            }
            default_model = strdup(line);
        }
        fclose(fp);
    }
    return default_model;
}

// 设置为默认模型的回调函数
static void set_as_default_model(GtkMenuItem *menuitem, gpointer user_data) {
    (void)menuitem;
    GtkComboBoxText *combo = GTK_COMBO_BOX_TEXT(user_data);
    const char* current_model = gtk_combo_box_text_get_active_text(combo);
    if (current_model) {
        save_default_model(current_model);
    }
}

// 右键菜单处理函数
static gboolean on_model_combo_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
    (void)user_data;
    if (event->button == 3) { // 右键点击
        GtkWidget *menu = gtk_menu_new();
        GtkWidget *menu_item = gtk_menu_item_new_with_label("设为默认模型");
        g_signal_connect(menu_item, "activate", G_CALLBACK(set_as_default_model), widget);
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
        gtk_widget_show_all(menu);
        gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent*)event);
        return TRUE;
    }
    return FALSE;
}

void load_models() {
    CURL* curl = curl_easy_init();
    if(curl) {
        MemoryStruct chunk = {.memory = malloc(1), .size = 0};
        if(!chunk.memory) {
            curl_easy_cleanup(curl);
            return;
        }
        
        curl_easy_setopt(curl, CURLOPT_URL, "http://localhost:11434/api/tags");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);
        
        CURLcode res = curl_easy_perform(curl);
        if(res == CURLE_OK && chunk.size > 0) {
            json_object* json = json_tokener_parse(chunk.memory);
            if(json) {
                json_object* models;
                if(json_object_object_get_ex(json, "models", &models)) {
                    int count = json_object_array_length(models);
                    char* default_model = load_default_model();
                    int default_index = 0;
                    
                    for(int i = 0; i < count; i++) {
                        json_object* item = json_object_array_get_idx(models, i);
                        json_object* name;
                        if(json_object_object_get_ex(item, "name", &name)) {
                            const char* model_name = json_object_get_string(name);
                            gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(model_combo), model_name);
                            // 如果是默认模型，记录索引
                            if (default_model && strcmp(model_name, default_model) == 0) {
                                default_index = i;
                            }
                        }
                    }
                    // 设置默认模型
                    gtk_combo_box_set_active(GTK_COMBO_BOX(model_combo), default_index);
                    if (default_model) free(default_model);
                }
                json_object_put(json);
            }
        }
        
        free(chunk.memory);
        curl_easy_cleanup(curl);
    }
    // 如果没有任何模型，设置第一个为活动项
    if (gtk_combo_box_get_active(GTK_COMBO_BOX(model_combo)) == -1) {
        gtk_combo_box_set_active(GTK_COMBO_BOX(model_combo), 0);
    }
}

void apply_font_size() {
    GtkCssProvider *provider = gtk_css_provider_new();
    gchar *css_data = g_strdup_printf(
        "textview { font-size: %dpt; } "
        "entry { font-size: %dpt; }",
        current_font_size, current_font_size);
    
    gtk_css_provider_load_from_data(provider, css_data, -1, NULL);
    gtk_style_context_add_provider_for_screen(gdk_screen_get_default(),
        GTK_STYLE_PROVIDER(provider), 
        GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
    
    g_free(css_data);
}

void create_ui(GtkApplication* app) {
    GtkWidget* window = gtk_application_window_new(app);
    if (!window) {
        g_warning("Failed to create application window");
        return;
    }
    
    g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_widget_destroyed), &window);
    
    gtk_window_set_title(GTK_WINDOW(window), "聊天助手");
    gtk_window_set_default_size(GTK_WINDOW(window), 600, 500);
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);

    GtkWidget* grid = gtk_grid_new();
    if (!grid) {
        g_warning("Failed to create grid");
        gtk_widget_destroy(window);
        return;
    }
    
    gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
    gtk_container_add(GTK_CONTAINER(window), grid);

    model_combo = gtk_combo_box_text_new();
    if (!model_combo) {
        g_warning("Failed to create model combo box");
        gtk_widget_destroy(window);
        return;
    }
    
    // 添加右键菜单支持
    g_signal_connect(model_combo, "button-press-event", 
                    G_CALLBACK(on_model_combo_button_press), NULL);
    
    gtk_widget_set_hexpand(model_combo, TRUE);
    gtk_grid_attach(GTK_GRID(grid), model_combo, 0, 0, 2, 1);

    GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
    if (!scrolled) {
        g_warning("Failed to create scrolled window");
        gtk_widget_destroy(window);
        return;
    }
    
    gtk_widget_set_hexpand(scrolled, TRUE);
    gtk_widget_set_vexpand(scrolled, TRUE);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
                                 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    
    chat_view = gtk_text_view_new();
    if (!chat_view) {
        g_warning("Failed to create text view");
        gtk_widget_destroy(window);
        return;
    }
    
    chat_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(chat_view));
    if (!chat_buffer) {
        g_warning("Failed to get text buffer");
        gtk_widget_destroy(window);
        return;
    }
    
    gtk_text_view_set_editable(GTK_TEXT_VIEW(chat_view), FALSE);
    gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(chat_view), TRUE);
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(chat_view), GTK_WRAP_WORD_CHAR);
    
    gtk_container_add(GTK_CONTAINER(scrolled), chat_view);
    gtk_grid_attach(GTK_GRID(grid), scrolled, 0, 1, 2, 1);

    user_tag = gtk_text_buffer_create_tag(chat_buffer, "user",
        "foreground", "#2E8B57",
        "weight", PANGO_WEIGHT_BOLD,
        "left-margin", 10,
        NULL);
    
    assistant_tag = gtk_text_buffer_create_tag(chat_buffer, "assistant",
        "foreground", "#1E90FF",
        "weight", PANGO_WEIGHT_BOLD,
        "left-margin", 10,
        NULL);

    timestamp_tag = gtk_text_buffer_create_tag(chat_buffer, "timestamp",
        "foreground", "#666666",
        "scale", 0.9,
        "left-margin", 10,
        NULL);

    GtkWidget* input_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
    if (!input_box) {
        g_warning("Failed to create input box");
        gtk_widget_destroy(window);
        return;
    }
    
    input_entry = gtk_entry_new();
    if (!input_entry) {
        g_warning("Failed to create input entry");
        gtk_widget_destroy(window);
        return;
    }
    
    gtk_entry_set_placeholder_text(GTK_ENTRY(input_entry), "输入您的问题...");
    g_signal_connect(input_entry, "activate", G_CALLBACK(send_click), NULL);
    gtk_box_pack_start(GTK_BOX(input_box), input_entry, TRUE, TRUE, 0);
    
    send_button = gtk_button_new_with_label("发送");
    if (!send_button) {
        g_warning("Failed to create send button");
        gtk_widget_destroy(window);
        return;
    }
    
    g_signal_connect(send_button, "clicked", G_CALLBACK(send_click), NULL);
    gtk_box_pack_start(GTK_BOX(input_box), send_button, FALSE, FALSE, 0);
    gtk_grid_attach(GTK_GRID(grid), input_box, 0, 2, 2, 1);

    apply_font_size();
    gtk_widget_show_all(window);
    load_models();
    load_history();  // 加载历史记录
}

static void cleanup_resources();
__attribute__((unused)) static void free_chat_message(ChatMessage* msg);

static void cleanup_resources() {
    // 防止重复清理
    if (cleanup_in_progress) return;
    cleanup_in_progress = true;
    
    // 首先停止任何正在进行的 AI 响应
    stop_ai_response();
    
    // 清理历史记录
    if (history) {
        g_queue_free_full(history, g_free);
        history = NULL;
    }
    
    // 清理当前编辑内容
    if (current_editing) {
        g_free(current_editing);
        current_editing = NULL;
    }
    
    // 清理 GTK 组件 - 按照依赖关系的反序清理
    
    // 首先清理标签，因为它们依赖于 chat_buffer
    if (chat_buffer && GTK_IS_TEXT_BUFFER(chat_buffer)) {
        if (user_tag && G_IS_OBJECT(user_tag)) {
            g_object_unref(user_tag);
            user_tag = NULL;
        }
        if (assistant_tag && G_IS_OBJECT(assistant_tag)) {
            g_object_unref(assistant_tag);
            assistant_tag = NULL;
        }
        if (timestamp_tag && G_IS_OBJECT(timestamp_tag)) {
            g_object_unref(timestamp_tag);
            timestamp_tag = NULL;
        }
    }
    
    // 然后清理文本视图和其他 GTK 组件
    if (chat_view && GTK_IS_WIDGET(chat_view)) {
        gtk_widget_destroy(chat_view);
        chat_view = NULL;
    }
    
    if (input_entry && GTK_IS_WIDGET(input_entry)) {
        gtk_widget_destroy(input_entry);
        input_entry = NULL;
    }
    
    if (send_button && GTK_IS_WIDGET(send_button)) {
        gtk_widget_destroy(send_button);
        send_button = NULL;
    }
    
    if (model_combo && GTK_IS_WIDGET(model_combo)) {
        gtk_widget_destroy(model_combo);
        model_combo = NULL;
    }
    
    // 清理 chat_buffer (在组件销毁后)
    if (chat_buffer) {
        chat_buffer = NULL; // GTK 会自动处理缓冲区的释放
    }
    
    // 最后清理 CURL
    curl_global_cleanup();
    
    cleanup_in_progress = false;
}

// 添加用于清理聊天消息的辅助函数
__attribute__((unused)) static void free_chat_message(ChatMessage* msg) {
    if (!msg) return;
    g_free(msg->role);
    g_free(msg->content);
    g_free(msg);
}

int main(int argc, char* argv[]) {
#ifdef _WIN32
    FreeConsole();
#endif

    const char* home_dir = getenv("HOME");
    if (!home_dir) {
        g_warning("HOME environment variable not set");
        home_dir = ".";
    }

    char* resolved_path = realpath(home_dir, NULL);
    if (!resolved_path) {
        g_warning("Failed to resolve home directory path");
        return 1;  // 返回错误状态
    }

    snprintf(chat_history_file, sizeof(chat_history_file), 
             "%s/.ollama_chat_history", resolved_path);
    snprintf(chat_input_history_file, sizeof(chat_input_history_file), 
             "%s/.ollama_input_history", resolved_path);
    snprintf(default_model_file, sizeof(default_model_file),
             "%s/.ollama_default_model", resolved_path);
    free(resolved_path);

    history = g_queue_new();
    curl_global_init(CURL_GLOBAL_ALL);

    gtk_init(&argc, &argv);
    GtkApplication* app = gtk_application_new("org.example.chat", G_APPLICATION_DEFAULT_FLAGS);
    g_signal_connect(app, "activate", G_CALLBACK(create_ui), NULL);
    
    int status = g_application_run(G_APPLICATION(app), argc, argv);
    
    cleanup_resources();
    g_object_unref(app);
    
    return status;
}
